﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

using Furion;
using Microsoft.Extensions.DependencyInjection;
using Neto.Core.Entities;
using Neto.Db.SqlSugar;
using SqlSugar;
using Yitter.IdGenerator;

namespace Neto.DataBase.Core;

[AppStartup(800)]
public sealed class DatabaseCoreStartup : AppStartup
{
    public void ConfigureServices(IServiceCollection services)
    {
        var dboptions = AppX.GetConfig<SqlSugarDbSettingOptions>();
        if (dboptions.EnableYitterIdGenerator)
            //5.1.3.53 起可用，自定义雪花ID使用
            StaticConfig.CustomSnowFlakeFunc = YitIdHelper.NextId;
        //遇到这个错误，需要设置为false
        //异常内容：System.ArgumentException: Cannot write DateTimeOffset with Offset=08:00:00 to PostgreSQL type 'timestamp with time zone', only offset 0 (UTC) is supported.  (Parameter 'value')
        //StaticConfig.AppContext_ConvertInfinityDateTime = false; //

        if (dboptions.EnableInitDataSeed)
            //此设置需要在  services.AddSqlsugarSetup 之前注册
            // 初始化数据种子委托方法扩展，执行完数据种子方法后调用，处理一些特殊扩展
            SqlSugarHelper.InitDataSeedExFunc = _db => true;

        //如果使用 SqlSugar 需要注册此服务
        services.AddSqlsugarSetup(App.Configuration);

        //实体数据改变监听实体
        SqlSugarEdclHelper.Adds(["SysLocalization", "SysLocalizationTranslation"]);

        //如使用非 EFCore ORM 框架，可实现 IUnitOfWork 接口之后调用 services.AddUnitOfWork<TUnitOfWork>() 注册即可
        services.AddUnitOfWork<SqlSugarUnitOfWork>();

        #region 差异日志全局配置

        // //按实际需要，指定需要记录差异日志的表，不要全局配置，根据业务需要配置
        // //程序启动时注册
        // StaticConfig.CompleteInsertableFunc=
        //     StaticConfig.CompleteUpdateableFunc=
        //         StaticConfig.CompleteDeleteableFunc = it => //it是具体的对象Updateable<T>等是个object
        //         {
        //
        //             //反射的方法可能多个就需要用GetMethods().Where
        //             var method = it.GetType().GetMethod("EnableDiffLogEvent");
        //             method.Invoke(it,new object[] { null });
        //
        //             //技巧：
        //             //可以定义一个接口只要是这个接口的才走这个逻辑
        //             //if(db.GetType().GenericTypeArguments[0].GetInterfaces().Any(it=>it==typeof(IDiff))
        //             //可以根据类型写if
        //             //if(x.GetType().GenericTypeArguments[0] = typeof(Order)) {   }
        //         };
        //
        // //注册完就
        // //Insertable、Updateable和Deleteable就会自动调用EnableDiffLogEvent()
        //

        #endregion


        #region 配置查询

        //https://www.donet5.com/Home/Doc?typeId=2309
        var types = SqlSugarHelper.Db.Queryable<SysDataConfig>().Select(it => it.GroupName).Distinct().ToList();
        //上面有耗时操作写在Any上面，保证程序启动后只执行一次
        if (!SqlSugarHelper.Db.ConfigQuery.Any())
            //数据字典配置
            foreach (var type in types)
                SqlSugarHelper.Db.ConfigQuery.SetTable<SysDataConfig>(it => it.Key, it => it.Name, type,
                    it => it.GroupName == type);
        //联表配置
        //db.ConfigQuery.SetTable<Order>(it => it.Id, it => it.Name);

        #endregion
    }
}